#include "stdafx.h"
#include "RecordContainer.h"
#include "File\Record.h"



CRecordContainer::CRecordContainer()
{
}


CRecordContainer::~CRecordContainer()
{
}



void  CRecordContainer::Add(CRecord* pRecord)
{
	mRecordList.push_back(pRecord);
	//mSize  += pRecord->mSize;
	pRecord->mContainer  = this;
	IncreaseSize(pRecord->mSize);

	if (pRecord->mStatus == RDS_VIRGIN) {
		mVirginNumber++;
		if (mContainer) {
			static_cast<CRecordContainer*> (mContainer)->IncreaseVirginNumber();		
		}		
	}

	
}



std::list<CRecord*> * CRecordContainer::GetRecordList()
{
	return &mRecordList;
}



CRecord* CRecordContainer::GetRecordWrapAround(CRecord* pRecord)
{
	//std::list<CRecord*>::iterator  iter  = mRecordList.begin();

	//for (; iter != mRecordList.end(); iter++) {
	//	if ((*iter)->mBeginTime <= pRecord->mEndTime && (*iter)->mEndTime >= pRecord->mEndTime) {
	//		return (*iter);
	//	}
	//}
	ASSERT(pRecord != NULL);
	return GetRecordWrapAround(pRecord->mBeginTime, pRecord->mEndTime);
}



CRecord* CRecordContainer::GetRecordWrapAround(CTime& begin, CTime& end)
{
	std::list<CRecord*>::iterator iter  = mRecordList.begin();



	for (; iter != mRecordList.end(); iter++) {
		if ((*iter)->mBeginTime <= begin && (*iter)->mEndTime >= end) {
			return (*iter);
		}
	}
	return NULL;
}


CRecord* CRecordContainer::GetFirst()
{
	if (!mRecordList.empty()) {
		return mRecordList.front();
	}

	return NULL;
}


CRecord* CRecordContainer::GetLast()
{
	if (!mRecordList.empty()) {
		 return mRecordList.back();
	}
	return NULL;
}



CRecord* CRecordContainer::GetPrevRecord(CRecord* pCurrRecord)
{
	if (mRecordList.size() > 1) {
		std::list<CRecord*>::reverse_iterator iter = mRecordList.rbegin();

		for (; iter != mRecordList.rend(); iter++) {
			if ((*iter) == pCurrRecord) {
				iter++;
				break;
			}
		}

		if (iter != mRecordList.rend()) {
			return (*iter);
		}
		else {
			return NULL;
		}
	}
	else {
		return NULL;
	}
}



CRecord* CRecordContainer::GetNextRecord(CRecord* pCurrRecord)
{
	if (mRecordList.size() > 1) {
		std::list<CRecord*>::iterator iter  = mRecordList.begin();

		for (; iter != mRecordList.end(); iter++) {
			if ((*iter) == pCurrRecord) {
				iter++;
				break;
			}
		}

		if (iter != mRecordList.end()) {
			return (*iter);
		}
		else {
			return NULL;
		}
	}
	else {
		return NULL;
	}
}



UINT CRecordContainer::GetVirginNumber()
{
	return mVirginNumber;
}



UINT CRecordContainer::DecreaseVirginNumber()
{
	if (mVirginNumber > 0) {
		mVirginNumber--;

		if (mContainer) {
			static_cast<CRecordContainer*>(mContainer)->DecreaseVirginNumber();
		}

		return mVirginNumber;
	}
	else {
		Print("Execption : Virgin number decrease but it has been 0");
		ASSERT(FALSE);
		return 0;
	}
}


UINT CRecordContainer::IncreaseVirginNumber()
{
	mVirginNumber++;

	if (mContainer) {	
		static_cast<CRecordContainer*>(mContainer)->IncreaseVirginNumber();
	}

	return mVirginNumber;
	return 0;
}



void CRecordContainer::IncreaseSize(ULONGLONG size)
{
	mSize += size;

	if (mContainer) {
		static_cast<CRecordContainer*> (mContainer)->IncreaseSize(size);
	}
}



void CRecordContainer::DecreaseSize(ULONGLONG size)
{
	if (mSize >= size) {
		mSize -= size;
		if (mContainer) {
			static_cast<CRecordContainer*>(mContainer)->DecreaseSize(size);
		}
	}
	else {
		Print("Container size too small");
		ASSERT(FALSE);
	}
}




void CRecordContainer::Remove(CRecord* pRecord)
{
	mRecordList.remove(pRecord);
	Print("biu----------mSize = %d pRecord->mSize", mSize, pRecord->mSize);
	if (mSize >= pRecord->mSize) {
		DecreaseSize(pRecord->mSize);

		if (pRecord->mStatus == RDS_VIRGIN) {
			if (mVirginNumber > 0) {
				mVirginNumber--;
			}
			else {
				Print("Container has no enough virgin");
				ASSERT(FALSE);
			}
		}
	}
	else {
		Print("Container is too small when remove");
		Print("Container Size:%d ,mSize%d",mSize,pRecord->mSize);
		ASSERT(FALSE);
	}
}



void CRecordContainer::Fuck()
{
	if (mRecordList.size() > 0) {
		std::list<CRecord*>::iterator iter  = mRecordList.begin();
		for (; iter != mRecordList.end(); iter++) {
			(*iter)->Fuck();
		}
	}

	if (mStatus == RDS_VIRGIN) {
		mStatus  = RDS_NORMAL;
	}

	mVirginNumber  = 0;
}